/*
 * MarkovChainParametersForm.java
 *
 * Created on 8 de Julho de 2011, 15:51
 */

package intopo.demonstrator.partnerselection.gui;

import intopo.demonstrator.partnerselection.Parameters;
import util.math.Rational;

import java.awt.Color;
import java.beans.*;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;

/**
 *
 * @author  pedro
 */
public class MarkovChainParametersForm
	extends javax.swing.JPanel
	implements
		java.io.Serializable
{
	/**
	 */
	private PropertyChangeSupport propertySupport;
	transient private Listener listener = new Listener ();
	/** Creates new form BeanForm */
	public MarkovChainParametersForm ()
	{
		propertySupport = new PropertyChangeSupport (this);
		initComponents ();
		updateComponents ();
	}
	/**
	 * Update the components with the attributes of the parameters.
	 * 
	 * <p> There is a single instance of the classes that represent the partner selection model.  These are static attributes in class {@code DataModel}.
	 * 
	 * @see DataModel
	 */
	public void updateComponents ()
	{
//		Parameters oldParameters = this.parameters;
//		this.parameters = p;
//		propertySupport.firePropertyChange ("parameters", oldParameters, this.parameters);
		removeListener ();
		poolSizeTextField.setText (String.valueOf (DataModel.parameters.getPoolSize ()));
		bitsTextField.setText (String.valueOf (DataModel.parameters.getNumberBitsProbability ()));
		deltaTextField.setText (DataModel.parameters.getDelta ().toString ());
		frequencyFormattedTextField.setText (DataModel.parameters.getProbabilityDrawAcceptableCombination ().toString ());
		addListener ();
	}
	private void addListener ()
	{
		poolSizeTextField.getDocument ().addDocumentListener (listener);
		bitsTextField.getDocument ().addDocumentListener (listener);
		deltaTextField.getDocument ().addDocumentListener (listener);
		frequencyFormattedTextField.getDocument ().addDocumentListener (listener);
	}
	private void removeListener ()
	{
		poolSizeTextField.getDocument ().removeDocumentListener (listener);
		bitsTextField.getDocument ().removeDocumentListener (listener);
		deltaTextField.getDocument ().removeDocumentListener (listener);
		frequencyFormattedTextField.getDocument ().removeDocumentListener (listener);
	}
	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
   // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
   private void initComponents() {
      java.awt.GridBagConstraints gridBagConstraints;
      javax.swing.JLabel jLabel1;
      javax.swing.JLabel jLabel2;
      javax.swing.JLabel jLabel3;
      javax.swing.JLabel jLabel4;

      jLabel1 = new javax.swing.JLabel();
      poolSizeTextField = new javax.swing.JTextField();
      jLabel2 = new javax.swing.JLabel();
      deltaTextField = new javax.swing.JTextField();
      jLabel3 = new javax.swing.JLabel();
      bitsTextField = new javax.swing.JTextField();
      jLabel4 = new javax.swing.JLabel();
      frequencyFormattedTextField = new javax.swing.JFormattedTextField();

      setLayout(new java.awt.GridBagLayout());

      setBorder(javax.swing.BorderFactory.createTitledBorder("parameters"));
      jLabel1.setText("pool size: ");
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
      add(jLabel1, gridBagConstraints);

      poolSizeTextField.setColumns(10);
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
      add(poolSizeTextField, gridBagConstraints);

      jLabel2.setText("delta: ");
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.gridy = 1;
      gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
      add(jLabel2, gridBagConstraints);

      deltaTextField.setColumns(5);
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.gridy = 1;
      gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
      add(deltaTextField, gridBagConstraints);

      jLabel3.setText("#bits probability: ");
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.gridy = 2;
      gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
      add(jLabel3, gridBagConstraints);

      bitsTextField.setColumns(10);
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.gridy = 2;
      gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
      add(bitsTextField, gridBagConstraints);

      jLabel4.setText("acceptable probability: ");
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.gridy = 3;
      gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
      add(jLabel4, gridBagConstraints);

      frequencyFormattedTextField.setColumns(10);
      frequencyFormattedTextField.setToolTipText("Probability to draw an acceptable combination");
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.gridy = 3;
      gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
      add(frequencyFormattedTextField, gridBagConstraints);

   }// </editor-fold>//GEN-END:initComponents
	
	
   // Variables declaration - do not modify//GEN-BEGIN:variables
   private javax.swing.JTextField bitsTextField;
   private javax.swing.JTextField deltaTextField;
   private javax.swing.JFormattedTextField frequencyFormattedTextField;
   private javax.swing.JTextField poolSizeTextField;
   // End of variables declaration//GEN-END:variables
	
	public void addPropertyChangeListener (PropertyChangeListener listener)
	{
		propertySupport.addPropertyChangeListener (listener);
	}

	public void removePropertyChangeListener (PropertyChangeListener listener)
	{
		propertySupport.removePropertyChangeListener (listener);
	}
	/**
	 * Inner class that implements the document listener used by the text fields of the enclosing class.
	 */
	private class Listener
		implements
			javax.swing.event.DocumentListener,
			java.io.Serializable
	{
		public void changedUpdate (DocumentEvent e) {
			updateParameter (e);
		}
		public void insertUpdate (DocumentEvent e) {
			updateParameter (e);
		}
		public void removeUpdate (DocumentEvent e) {
			updateParameter (e);
		}
		/**
		 * Updates the parameter corresponding to the text field that caused the document event.
		 */
		private void updateParameter (DocumentEvent e)
		{
			javax.swing.JTextField tf = null;
			try {
				if (e.getDocument () == bitsTextField.getDocument ()) {
					tf = bitsTextField;
					DataModel.parameters.setNumberBitsProbability (Integer.parseInt (bitsTextField.getText ()));
				}
				else if (e.getDocument () == poolSizeTextField.getDocument ()) {
					tf = poolSizeTextField;
					DataModel.parameters.setPoolSize (Integer.parseInt (poolSizeTextField.getText ()));
				}
				else if (e.getDocument () == deltaTextField.getDocument ()) {
					tf = deltaTextField;
					DataModel.parameters.setDelta (new Rational (deltaTextField.getText ()));
				}
				else if (e.getDocument () == frequencyFormattedTextField.getDocument ()) {
					tf = frequencyFormattedTextField;
					DataModel.parameters.setProbabilityDrawAcceptableCombination (new Rational (frequencyFormattedTextField.getText ()));
				}
				else {
					throw new Error ("Not reachable");
				}
				tf.setForeground (Color.BLACK);
				propertySupport.firePropertyChange ("parameters", null, DataModel.parameters);
			}
			catch (NumberFormatException ex) {
				tf.setForeground (Color.RED);
			}
			catch (IllegalArgumentException ex) {
				tf.setForeground (Color.MAGENTA);
			}
		}
//		/**
//		 * Checks if the given text field has an integer in the given domain.
//		 */
//		private void checkInt (JTextField tf, int min, int max)
//			throws NumberFormatException, IllegalArgumentException
//		{
//			int v = Integer.parseInt (tf.getText ());
//			if (v < min || v > max) {
//				throw new IllegalArgumentException ();
//			}
//		}
//		private void checkRational (JTextField tf, Rational min, Rational max)
//		{
//			Rational r = new Rational (tf.getText ());
//			if (r.compareTo (min) < 0 || r.compareTo (max) > 0) {
//				throw new IllegalArgumentException ();
//			}
//		}
//		/**
//		 * Checks if the given text field has a floating number in the given domain.
//		 */
//		private void checkFloat (JTextField tf, float min, float max)
//			throws NumberFormatException, IllegalArgumentException
//		{
//			float v = Float.parseFloat (tf.getText ());
//			if (v < min || v > max) {
//				throw new IllegalArgumentException ();
//			}
//		}
	}
}
